package com.yixun.qfbao.api.service.impl;

import com.yixun.common.page.Page;
import com.yixun.qfbao.api.service.AgencyReportService;
import com.yixun.qfbao.api.service.DeptPermissionService;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.common.model.PageDTO;
import com.yixun.qfbao.dao.AgencyReportDao;
import com.yixun.qfbao.dao.DepartmentDao;
import com.yixun.qfbao.model.*;
import com.yixun.qfbao.model.dto.DepartmentDto;
import com.yixun.qfbao.service.CompanyRelationService;
import com.yixun.qfbao.util.DateStyle;
import com.yixun.qfbao.util.DateUtils;
import com.yixun.qfbao.xf.model.enums.DeptPermissionEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.lang.Long.parseLong;
import static java.util.Arrays.asList;

@Service
public class AgencyReportServiceImpl implements AgencyReportService {

    @Autowired
    AgencyReportDao agencyReportDao;
    @Autowired
    DepartmentDao departmentDao;
    @Autowired
    CompanyRelationService companyRelationService;
    @Lazy
    @Autowired
    DeptPermissionService deptPermissionService;

    @Override
    public GetAgencyDeptResDto getAgencyDept(GetAgencyDeptReqDto reqDto) {
        GetAgencyDeptResDto resDto = new GetAgencyDeptResDto();
        DepartmentDto entity = new DepartmentDto();
        entity.setMerchantId(reqDto.getAgentCompany());
        entity.setOrders("t.merchant_id, t.permission_code");
        List<Department> deptList = departmentDao.selectListByDto(entity);
        resDto.setList(deptList);
        return resDto;
    }

    @Override
    public AgencyHisReportedPremisesResDto getAgencyHisReportedPremises(AgencyHisReportedPremisesReqDto reqDto) {
        AgencyHisReportedPremisesResDto resDto = new AgencyHisReportedPremisesResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        List<AgencyHisReportedPremises> rows = agencyReportDao.getAgencyHisReportedPremises(param);
        resDto.setList(rows);
        return resDto;
    }

    @Override
    public AgencyPremisesSalesReportResDto getAgencyPremisesSalesReport(AgencyPremisesSalesReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyPremisesSalesReportResDto resDto = new AgencyPremisesSalesReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getSaleStatus())){
            param.setSaleStatuses(Stream.of(reqDto.getSaleStatus().split(",")).collect(Collectors.toList()));
        }
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }
        param.setValidateData(reqDto.isValidateData());

        if ("1".equals(reqDto.getAccountType())) {
            AgencyPartnerPermission app = deptPermissionService.getAgencyPartnerPermission(Long.valueOf(reqDto.getUserId()));
            if(Objects.isNull(app) || DeptPermissionEnum.MYSELF.getNo().equals(app.getDeptPermission())){
                // 未配置权限或本人权限,以当前用户查询报备记录
                param.setStaffIds(asList(parseLong(reqDto.getUserId())));
            }else if(DeptPermissionEnum.DEPT.getNo().equals(app.getDeptPermission())){
                // 本部,获取用户及其子部门相关所有部门报备数据
                param.setAgencyDeptIds(app.getPermissionIds());
            }
        }

        int count = agencyReportDao.getAgencyPremisesSalesReportCount(param);
        List<AgencyPremisesSalesReport> rows = agencyReportDao.getAgencyPremisesSalesReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        Page<AgencyPremisesSalesReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }

    @Override
    public AgencyCompanyReportResDto getAgencyCompanyReport(AgencyCompanyReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyCompanyReportResDto resDto = new AgencyCompanyReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getSaleStatus())){
            param.setSaleStatuses(Stream.of(reqDto.getSaleStatus().split(",")).collect(Collectors.toList()));
        }
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }
        param.setValidateData(reqDto.isValidateData());
        if ("1".equals(reqDto.getAccountType())) {
            AgencyPartnerPermission app = deptPermissionService.getAgencyPartnerPermission(Long.valueOf(reqDto.getUserId()));
            if(Objects.isNull(app) || DeptPermissionEnum.MYSELF.getNo().equals(app.getDeptPermission())){
                // 未配置权限或本人权限,以当前用户查询报备记录
                param.setStaffIds(Collections.singletonList(parseLong(reqDto.getUserId())));
                param.setAgencyDeptIds(Collections.singletonList(reqDto.getDeptId()));
            }else if(DeptPermissionEnum.DEPT.getNo().equals(app.getDeptPermission())){
                // 本部,获取用户及其子部门相关所有部门报备数据
                param.setAgencyDeptIds(app.getPermissionIds());
            }
        }
        int count = agencyReportDao.getAgencyCompanyReportCount(param);
        List<AgencyCompanyReport> rows = agencyReportDao.getAgencyCompanyReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        DepartmentDto departmentDto = new DepartmentDto();
        departmentDto.setMerchantIds(String.valueOf(reqDto.getStaffCompanyId()));
        List<DepartmentDto> departmentDtoList = departmentDao.selectPrincipalNameByCompany(departmentDto);
        Map<Long, String> departmentMap = departmentDtoList.stream()
                .collect(Collectors.toMap(DepartmentDto::getMerchantId, DepartmentDto::getPrincipalName, (oldData, newData) -> newData));
        rows.forEach(item -> {
            item.setPrincipalName(departmentMap.get(item.getCompanyId()));
        });
        Page<AgencyCompanyReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }

    @Override
    public AgencyOrgReportResDto getAgencyOrgReport(AgencyOrgReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyOrgReportResDto resDto = new AgencyOrgReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setLayer(reqDto.getLayer());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }

        if ("1".equals(reqDto.getAccountType())) {
            AgencyPartnerPermission app = deptPermissionService.getAgencyPartnerPermission(Long.valueOf(reqDto.getUserId()));
            if(Objects.isNull(app) || DeptPermissionEnum.MYSELF.getNo().equals(app.getDeptPermission())){
                // 未配置权限或本人权限,以当前用户查询报备记录
                param.setStaffIds(Collections.singletonList(parseLong(reqDto.getUserId())));
                param.setAgencyDeptIds(Collections.singletonList(reqDto.getDeptId()));
            }else if(DeptPermissionEnum.DEPT.getNo().equals(app.getDeptPermission())){
                // 本部,获取用户及其子部门相关所有部门报备数据
                param.setAgencyDeptIds(app.getPermissionIds());
            }
        }

        int count = 0;
        List<AgencyOrgReport> rows = agencyReportDao.getAgencyOrgReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        if(reqDto.getMergeDept()){
            pageDTO.setPageNum(PageDTO.DEFAULT_PAGENUM);
            pageDTO.setPageSize(PageDTO.MAX_PAGESIZE);
            List<AgencyOrgReport> allRows = agencyReportDao.getAgencyOrgReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());
            count = allRows.size();
            rows = mergeAgencyOrgReport(rows, allRows);
        }else {
            count = agencyReportDao.getAgencyOrgReportCount(param);
        }

        Page<AgencyOrgReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }

    // 合并记录
    List<AgencyOrgReport> mergeAgencyOrgReport(List<AgencyOrgReport> rows, List<AgencyOrgReport> allRows){
        for (AgencyOrgReport aor: rows){
            Long countOne = aor.getCountOne();
            Long countTwo = aor.getCountTwo();
            Long countThree = aor.getCountThree();
            Long countFour = aor.getCountFour();
            Long countFive = aor.getCountFive();
            Long countSix = aor.getCountSix();
            Long countSeven = aor.getCountSeven();
            Long countEight = aor.getCountEight();
            Long countNine = aor.getCountNine();
            BigDecimal dealAmount = new BigDecimal(StringUtils.defaultIfBlank(aor.getDealAmount(), "0"));
            for (AgencyOrgReport allAor: allRows){
                if(!aor.getPermissionCode().equals(allAor.getPermissionCode())
                        && allAor.getPermissionCode().startsWith(aor.getPermissionCode())){
                    countOne += allAor.getCountOne();
                    countTwo += allAor.getCountTwo();
                    countThree += allAor.getCountThree();
                    countFour += allAor.getCountFour();
                    countFive += allAor.getCountFive();
                    countSix += allAor.getCountSix();
                    countSeven += allAor.getCountSeven();
                    countEight += allAor.getCountEight();
                    countNine += allAor.getCountNine();
                    dealAmount.add(new BigDecimal(StringUtils.defaultIfBlank(allAor.getDealAmount(), "0")));
                }
            }
            aor.setCountOne(countOne);
            aor.setCountTwo(countTwo);
            aor.setCountThree(countThree);
            aor.setCountFour(countFour);
            aor.setCountFive(countFive);
            aor.setCountSix(countSix);
            aor.setCountSeven(countSeven);
            aor.setCountEight(countEight);
            aor.setCountNine(countNine);
            aor.setDealAmount(String.valueOf(dealAmount));
        }
        return rows;
    }

    @Override
    public AgencyStoreReportResDto getAgencyStoreReport(AgencyStoreReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyStoreReportResDto resDto = new AgencyStoreReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }
        DepartmentDto staffDepartmentDto = new DepartmentDto();
        staffDepartmentDto.setParentId(0L);
        staffDepartmentDto.setMerchantId(reqDto.getStaffCompanyId());
        Department staffDepartment = departmentDao.selectByDto(staffDepartmentDto);
        if(staffDepartment == null){
            return resDto;
        }
        param.setAgencyTopDeptId(staffDepartment.getId());
        //获取门店的部门id
        List<Long> agencyDeptIds = new ArrayList<>();
        DepartmentDto departmentDto = new DepartmentDto();
        departmentDto.setParentId(staffDepartment.getId());
        List<Department> departmentList = departmentDao.selectListByDto(departmentDto);
        for(Department d : departmentList){
            agencyDeptIds.add(d.getId());
        }
        agencyDeptIds.add(staffDepartment.getId());
        param.setAgencyDeptIds(agencyDeptIds);

        int count = agencyReportDao.getAgencyStoreReportCount(param);
        List<AgencyStoreReport> rows = agencyReportDao.getAgencyStoreReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        Page<AgencyStoreReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }

    @Override
    public AgencyGroupReportResDto getAgencyGroupReport(AgencyGroupReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyGroupReportResDto resDto = new AgencyGroupReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getSaleStatus())){
            param.setSaleStatuses(Stream.of(reqDto.getSaleStatus().split(",")).collect(Collectors.toList()));
        }
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }
        param.setGroupName(reqDto.getGroupName());
        param.setValidateData(reqDto.isValidateData());

        DepartmentDto staffDepartmentDto = new DepartmentDto();
        staffDepartmentDto.setParentId(reqDto.getStoreId());
        staffDepartmentDto.setMerchantId(reqDto.getStaffCompanyId());
        staffDepartmentDto.setDepartmentName(reqDto.getGroupName());
        List<Department> departmentList = departmentDao.getListByName(staffDepartmentDto);
        if(CollectionUtils.isEmpty(departmentList)){
            return resDto;
        }
        //获取组别部门id
        List<Long> agencyDeptIds = departmentList.stream().map(Department::getId).collect(Collectors.toList());
        param.setAgencyDeptIds(agencyDeptIds);

        int count = agencyReportDao.getAgencyGroupReportCount(param);
        List<AgencyGroupReport> rows = agencyReportDao.getAgencyGroupReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        Page<AgencyGroupReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }

    @Override
    public AgencyAgentReportResDto getAgencyAgentReport(AgencyAgentReportReqDto reqDto, PageDTO pageDTO) throws ParseException {
        AgencyAgentReportResDto resDto = new AgencyAgentReportResDto();
        AgencyReportParam param = new AgencyReportParam();
        param.setAgentCompany(reqDto.getStaffCompanyId());
        param.setPremisesId(reqDto.getPremisesId());
        if(StringUtils.isNotEmpty(reqDto.getBeginDate())){
            param.setBeginDate(DateUtils.stringToDate(reqDto.getBeginDate(), DateStyle.YYYY_MM_DD.getValue()));
        }
        if(StringUtils.isNotEmpty(reqDto.getEndDate())){
            Date endDate = DateUtils.StringToDate(reqDto.getEndDate(), DateStyle.YYYY_MM_DD);
            endDate = DateUtils.addDay(endDate, 1);
            param.setEndDate(endDate);
        }
        List<Long> deptList = new ArrayList<>();
        if(Objects.nonNull(reqDto.getDeptId())){
            deptList = Collections.singletonList(reqDto.getDeptId());
            param.setAgencyDeptIds(deptList);
        }

        if ("1".equals(reqDto.getAccountType())) {
            AgencyPartnerPermission app = deptPermissionService.getAgencyPartnerPermission(Long.valueOf(reqDto.getUserId()));
            if(Objects.isNull(app) || DeptPermissionEnum.MYSELF.getNo().equals(app.getDeptPermission())){
                // 未配置权限或本人权限,以当前用户查询报备记录
                param.setStaffIds(asList(parseLong(reqDto.getUserId())));
            }else if(DeptPermissionEnum.DEPT.getNo().equals(app.getDeptPermission())){
                // 本部,获取用户及其子部门相关所有部门报备数据
                deptList.addAll(app.getPermissionIds());
                param.setAgencyDeptIds(deptList);
            }
        }

        int count = agencyReportDao.getAgencyAgentReportCount(param);
        List<AgencyAgentReport> rows = agencyReportDao.getAgencyAgentReportList(param, (pageDTO.getPageNum() - 1) * pageDTO.getPageSize(), pageDTO.getPageSize());

        Page<AgencyAgentReport> page = new Page<>(count, rows);
        page.setPageSize(pageDTO.getPageSize());
        page.setPageNumber(pageDTO.getPageNum());
        resDto.setPageModel(page);
        return resDto;
    }
}
